import LXCOM from '../../common/common.js'
import baseunitgrah from '../baseunitgrah.js'
import { CoordTRFUtil } from '../../common/tools/coordtool.js'
import Coord from '../../common/struct/coord.js'
import UtilFuncs from '../../common/tools/utilfuncs.js'
var funcs = UtilFuncs.UtilFuncs;

import GlobalConst from '../../common/globalConst.js'
var global = GlobalConst.GlobalConst;

import {FillUtil} from '../../graph/paintutil/fillutil.js'
import {Strokeutil} from '../../graph/paintutil/strokeutil.js'

import {LGXEnums}  from '../../common/sysenum.js'


import cube from '../../common/struct/basestruct/cube.js'
import fillinfo from "../../common/struct/fillinfo";
import singlepointaction from '../action/singlepointaction.js'
import { GlobalVar } from '../../common/globalvar.js'
import absgraph from '../absgraph.js'

class CubeGraph extends baseunitgrah.BaseUnitGraph {
    constructor(type) {
        super(type);
        this.m_graphType = LGXEnums.LGXGraphType.Cube_type;
        var pos = new Coord.PointPos();
        this.setPos(pos);
        this.width = 120;
        this.height = 90;
        this.depth = 15;
        this.ctrlPoint = new LXCOM.LGXPoint();
        this.coverFillDef = new fillinfo.LGXFillDefInfo();
        this.rightFillDef = new fillinfo.LGXFillDefInfo();
        var action = new singlepointaction.SinglePointAction(this);
        this.setActionSvc(action);
        this._fillDef.fillStyle = LGXEnums.LGXFillStyle.SOLID;
        this._fillDef.fillColor.clone(GlobalVar.visoDefaultFillColor);

        this.coverFillDef.fillStyle = LGXEnums.LGXFillStyle.SOLID;
        this.coverFillDef.fillColor.setVal(166,201,232);

        this.rightFillDef.fillStyle = LGXEnums.LGXFillStyle.SOLID;
        this.rightFillDef.fillColor.setVal(48,121,188);

        this._lineDef.color.setVal(0,0,0);

        this.lastMouseDownPt = new LXCOM.LGXPoint();
        this.sureSelKind = 0;//1--顶盖 2--前面 3--右侧面
    }

    

    display(map, mapInfo, forClip) {
        var trfFunc = this.convertWorldPt2Screen;
        this.disTopCover(trfFunc, map, mapInfo, forClip);
        this.disFront(trfFunc, map, mapInfo, forClip);
        this.disRightSide(trfFunc, map, mapInfo, forClip);
        this.displayFeaturePoint(map, mapInfo);
    }

    disInSymbol(transformInfo, map, mapInfo, forClip) {
        var trfFunc = this.convertLocalPt2Screen;
        this.disTopCover(trfFunc, map, mapInfo, forClip, transformInfo);
        this.disFront(trfFunc, map, mapInfo, forClip, transformInfo);
        this.disRightSide(trfFunc, map, mapInfo, forClip, transformInfo);
    }

    disRightSide(trfFunc, map, mapInfo, forClip, transformInfo) {
        var postion = this.getPos();
        let cntPt = { x: postion.x, y: postion.y };

        var cntWorldPT = this.getZone().getCnt();
        var cntScreenPT = trfFunc(cntWorldPT, mapInfo,transformInfo);
        let rotv = this.getRadAngle();

        map.save();
        map.translate(cntScreenPT.x, cntScreenPT.y);
        map.rotate(-rotv);
        map.scale(this.localScale.x, this.localScale.y);
        map.translate(-cntScreenPT.x, -cntScreenPT.y);
        map.beginPath();

        //右侧面左上角
        let x = cntPt.x + this.width / 2 - this.depth;
        let y = cntPt.y + this.height / 2 - this.depth;
        let sp1 = trfFunc({ x, y }, mapInfo,transformInfo);
        map.moveTo(sp1.x, sp1.y);

        //左下角
        x = cntPt.x + this.width / 2 - this.depth;
        y = cntPt.y - this.height / 2;
        let sp2 = trfFunc({ x, y }, mapInfo,transformInfo);
        map.lineTo(sp2.x, sp2.y);

        //右下角
        x = cntPt.x + this.width / 2;
        y = cntPt.y - this.height / 2 + this.depth;
        let sp3 = trfFunc({ x, y }, mapInfo,transformInfo);
        map.lineTo(sp3.x, sp3.y);

        //右上角
        x = cntPt.x + this.width / 2;
        y = cntPt.y + this.height / 2;
        let sp4 = trfFunc({ x, y }, mapInfo,transformInfo);
        map.lineTo(sp4.x, sp4.y);
        map.closePath();
        let paintSymFlag = false;
        if (transformInfo){
            paintSymFlag = true;
        }
        map.restore();
        if (!forClip) {
            Strokeutil.active(this._lineDef, this, map, mapInfo);
            FillUtil.active(this.rightFillDef, map, this, mapInfo, paintSymFlag, transformInfo);
        }
        
    }

    disFront(trfFunc, map, mapInfo, forClip, transformInfo) {
        var postion = this.getPos();
        let cntPt = { x: postion.x, y: postion.y };

        var cntWorldPT = this.getZone().getCnt();
        var cntScreenPT = trfFunc(cntWorldPT, mapInfo,transformInfo);
        let rotv = this.getRadAngle();

        map.save();
        map.translate(cntScreenPT.x, cntScreenPT.y);
        map.rotate(-rotv);
        map.scale(this.localScale.x, this.localScale.y);
        map.translate(-cntScreenPT.x, -cntScreenPT.y);
        map.beginPath();

        //前面左上角
        let x = cntPt.x - this.width / 2;
        let y = cntPt.y + this.height / 2 - this.depth;
        let sp1 = trfFunc({ x, y }, mapInfo,transformInfo);
        map.moveTo(sp1.x, sp1.y);

        //左下角
        x = cntPt.x - this.width / 2;
        y = cntPt.y - this.height / 2;
        let sp2 = trfFunc({ x, y }, mapInfo,transformInfo);
        map.lineTo(sp2.x, sp2.y);

        //右下角
        x = cntPt.x + this.width / 2 - this.depth;
        y = cntPt.y - this.height / 2;
        let sp3 = trfFunc({ x, y }, mapInfo,transformInfo);
        map.lineTo(sp3.x, sp3.y);

        //右上角
        x = cntPt.x + this.width / 2 - this.depth;
        y = cntPt.y + this.height / 2 - this.depth;
        let sp4 = trfFunc({ x, y }, mapInfo,transformInfo);
        map.lineTo(sp4.x, sp4.y);
        map.closePath();
        let paintSymFlag = false;
        if (transformInfo){
            paintSymFlag = true;
        }
        map.restore();
        if (!forClip) {
            Strokeutil.active(this._lineDef, this, map, mapInfo);
            FillUtil.active(this._fillDef, map, this, mapInfo, paintSymFlag, transformInfo);
        }
        
    }

    disTopCover(trfFunc, map, mapInfo, forClip, transformInfo) {
        var postion = this.getPos();
        let cntPt = { x: postion.x, y: postion.y };

        var cntWorldPT = this.getZone().getCnt();
        var cntScreenPT = trfFunc(cntWorldPT, mapInfo,transformInfo);
        let rotv = this.getRadAngle();

        map.save();
        map.translate(cntScreenPT.x, cntScreenPT.y);
        map.rotate(-rotv);
        map.scale(this.localScale.x, this.localScale.y);
        map.translate(-cntScreenPT.x, -cntScreenPT.y);
        map.beginPath();

        //顶盖左下角
        let x = cntPt.x - this.width / 2;
        let y = cntPt.y + this.height / 2 - this.depth;
        let sp1 = trfFunc({ x, y }, mapInfo,transformInfo);
        map.moveTo(sp1.x, sp1.y);

        //右下角
        x = cntPt.x + this.width / 2 - this.depth;
        y = cntPt.y + this.height / 2 - this.depth;
        let sp2 = trfFunc({ x, y }, mapInfo,transformInfo);
        map.lineTo(sp2.x, sp2.y);

        //右上角
        x = cntPt.x + this.width / 2;
        y = cntPt.y + this.height / 2;
        let sp3 = trfFunc({ x, y }, mapInfo,transformInfo);
        map.lineTo(sp3.x, sp3.y);

        //左上角
        x = cntPt.x - this.width / 2 + this.depth;
        y = cntPt.y + this.height / 2;
        let sp4 = trfFunc({ x, y }, mapInfo,transformInfo);
        map.lineTo(sp4.x, sp4.y);
        map.closePath();

        let paintSymFlag = false;
        if (transformInfo){
            paintSymFlag = true;
        }

        map.restore();
        if (!forClip) {
            Strokeutil.active(this._lineDef, this, map, mapInfo);
            FillUtil.active(this.coverFillDef, map, this, mapInfo, paintSymFlag, transformInfo);
        }
    }

    displayFeaturePoint(map, mapInfo) {
        if (this._selected && !mapInfo.paintForGenerateICON) {
            super.displayFeaturePoint(map, mapInfo);
            var point = CoordTRFUtil.world2Screen(this.ctrlPoint, mapInfo);
            this.drawFocusPoint(map, point.x, point.y, "#ffff00");
        }
    }

    distance(tPoint, scaling, mapscale) {
        if (!super.preCheckInScope(tPoint, scaling)) {
            return -1;
        }
        this.lastMouseDownPt.clone(tPoint);
        return 0;
    }

    calculateSubKind(tPoint, scaling, mapscale) {
        var nRefKind = 0;
        var cmpGap = super.getSelCmpGap(scaling, mapscale);
        let dis = funcs.distancePoint(tPoint, this.ctrlPoint, scaling);
        if (dis <= cmpGap && dis >= 0) {
            nRefKind = 2;
        }
        else {
            if (super.preCheckInScope(tPoint, scaling)) {
                nRefKind = 1;
            }
        }

        return nRefKind;
    }

    calScope(mapscale) {
        var postion = this.getPos();
        this._zone.left = (postion.x - this.width / 2);
        this._zone.bottom = (postion.y - this.height / 2);
        this._zone.right = (postion.x + this.width / 2);
        this._zone.top = (postion.y + this.height / 2);

        let ctrlPtLocal = { x: - this.width / 2, y: this.height / 2 - this.depth, z: 0 };
        let mtx = this.getLocalMatrix();
        let worldPt = mtx.MultT(ctrlPtLocal);//求相对于控制图形局部坐标系的局部坐标  
        this.ctrlPoint.x = worldPt.x;
        this.ctrlPoint.y = worldPt.y;
    }

    getLocalZone() {
        let rect = new LXCOM.LGXRect(0, 0, 0, 0);
        rect.left = (- this.width / 2);
        rect.bottom = (- this.height / 2);
        rect.right = (this.width / 2);
        rect.top = (this.height / 2);
        return rect;
    }

    getFeaturePtLst() {
        var postion = this.getPos();
        var ptlst = new Array;
        return ptlst;
    }


    movePosOffset(tOffset, modCmdInfo) {
        if (this._selKind < 1) {
            return;
        }
        var nRefKind = this._selKind;
        if (nRefKind == 1) {
            this.translate(tOffset, modCmdInfo.mapscale, false);
        }
        else if (nRefKind == 2) {
            this.depth -= tOffset.y;
        }
    }

    assignInfo(info) {
        super.assignInfo(info);
        this.width = info.width;
        this.height = info.height;
        this.depth = info.depth;

        if (info.coverFillDef){
            this.coverFillDef.clone(info.coverFillDef);
        }

        if (info.rightFillDef){
            this.rightFillDef.clone(info.rightFillDef);
        }
    }

    modifyAttribute(info, mapscale) {
        super.modifyCommonAttribute(info);
        this.width = info.width;
        this.height = info.height;
        this.depth = info.depth;

        if (info.coverFillDef){
            this.coverFillDef.clone(info.coverFillDef);
        }

        if (info.rightFillDef){
            this.rightFillDef.clone(info.rightFillDef);
        }

        this.calScope(mapscale);
    }

    toInfo() {
        var info = new cube.Cube();
        this.toInfo4InheritClass(info);
        info.width = this.width;
        info.height = this.height;
        info.x = this._position.x;
        info.y = this._position.y;
        info.depth = this.depth;

        if (this.coverFillDef.fillStyle != LGXEnums.LGXFillStyle.EMPTY){
            info.coverFillDef = new fillinfo.LGXFillDefInfo();
            info.coverFillDef.clone(this.coverFillDef);
        }

        if (this.rightFillDef.fillStyle != LGXEnums.LGXFillStyle.EMPTY){
            info.rightFillDef = new fillinfo.LGXFillDefInfo();
            info.rightFillDef.clone(this.rightFillDef);
        }

        return info;
    }


    getPosCopy() {
        let pos = new Coord.PointPos();
        pos.clone(this._position);
        return pos;
    }

    translateGradientFill(tOffset) {
        // this._fillDef.translate(tOffset.x, tOffset.y);
        // this.coverFillDef.translate(tOffset.x, tOffset.y);
        // this.rightFillDef.translate(tOffset.x, tOffset.y);
    }

    rotateGradientFill(rotCnt, radAngle) {
        // this._fillDef.rotate(rotCnt, radAngle);
        // this.coverFillDef.rotate(rotCnt, radAngle);
        // this.rightFillDef.rotate(rotCnt, radAngle);
    }

    getMainFeaturePTLst(tFeaturePTLst,transformInfo) {
        let mtx = this.getLocalMatrix();

        let halfwid = this.width / 2;
        let halfhgt = this.height / 2;

        //左上顶点
        let x = -halfwid;
        let y = halfhgt - this.depth;
        let worldPt = mtx.MultT({ x, y, z: 0 });
        let featurePT = { x: worldPt.x, y: worldPt.y, kind: 1 };
        featurePT = this.convertPt2World(featurePT,transformInfo);
        tFeaturePTLst.push({ pt: featurePT, kind: LGXEnums.AuxPointKind.end });

        //左侧中点
        x = -halfwid;
        y = -this.depth / 2;
        worldPt = mtx.MultT({ x, y, z: 0 });
        featurePT = { x: worldPt.x, y: worldPt.y, kind: 2 };
        featurePT = this.convertPt2World(featurePT,transformInfo);
        tFeaturePTLst.push({ pt: featurePT, kind: LGXEnums.AuxPointKind.end });

        //左下顶点
        x = -halfwid;
        y = -halfhgt;
        worldPt = mtx.MultT({ x, y, z: 0 });
        featurePT = { x: worldPt.x, y: worldPt.y, kind: 1 };
        featurePT = this.convertPt2World(featurePT,transformInfo);
        tFeaturePTLst.push({ pt: featurePT, kind: LGXEnums.AuxPointKind.end });

        //底部中点
        x = -this.depth / 2;
        y = -halfhgt;
        worldPt = mtx.MultT({ x, y, z: 0 });
        featurePT = { x: worldPt.x, y: worldPt.y, kind: 2 };
        featurePT = this.convertPt2World(featurePT,transformInfo);
        tFeaturePTLst.push({ pt: featurePT, kind: LGXEnums.AuxPointKind.lineMid });

        //前平面---------------------
        //右下顶点
        x = halfwid - this.depth;
        y = -halfhgt;
        worldPt = mtx.MultT({ x, y, z: 0 });
        featurePT = { x: worldPt.x, y: worldPt.y, kind: 1 };
        featurePT = this.convertPt2World(featurePT,transformInfo);
        tFeaturePTLst.push({ pt: featurePT, kind: LGXEnums.AuxPointKind.end });

        //右侧中点
        x = halfwid - this.depth;
        y = -this.depth / 2;
        worldPt = mtx.MultT({ x, y, z: 0 });
        featurePT = { x: worldPt.x, y: worldPt.y, kind: 2 };
        featurePT = this.convertPt2World(featurePT,transformInfo);
        tFeaturePTLst.push({ pt: featurePT, kind: LGXEnums.AuxPointKind.end });

        //右上顶点
        x = halfwid - this.depth;
        y = halfhgt - this.depth;
        worldPt = mtx.MultT({ x, y, z: 0 });
        featurePT = { x: worldPt.x, y: worldPt.y, kind: 1 };
        featurePT = this.convertPt2World(featurePT,transformInfo);
        tFeaturePTLst.push({ pt: featurePT, kind: LGXEnums.AuxPointKind.end });

        //顶部中点
        x = -this.depth / 2;
        y = halfhgt - this.depth;
        worldPt = mtx.MultT({ x, y, z: 0 });
        featurePT = { x: worldPt.x, y: worldPt.y, kind: 2 };
        featurePT = this.convertPt2World(featurePT,transformInfo);
        tFeaturePTLst.push({ pt: featurePT, kind: LGXEnums.AuxPointKind.lineMid });

        //后平面---------------------
        //右下顶点
        x = halfwid;
        y = -halfhgt + this.depth;
        worldPt = mtx.MultT({ x, y, z: 0 });
        featurePT = { x: worldPt.x, y: worldPt.y, kind: 1 };
        featurePT = this.convertPt2World(featurePT,transformInfo);
        tFeaturePTLst.push({ pt: featurePT, kind: LGXEnums.AuxPointKind.end });

        //右侧中点
        x = halfwid;
        y = this.depth / 2;
        worldPt = mtx.MultT({ x, y, z: 0 });
        featurePT = { x: worldPt.x, y: worldPt.y, kind: 2 };
        featurePT = this.convertPt2World(featurePT,transformInfo);
        tFeaturePTLst.push({ pt: featurePT, kind: LGXEnums.AuxPointKind.end });

        //右上顶点
        x = halfwid;
        y = halfhgt;
        worldPt = mtx.MultT({ x, y, z: 0 });
        featurePT = { x: worldPt.x, y: worldPt.y, kind: 1 };
        featurePT = this.convertPt2World(featurePT,transformInfo);
        tFeaturePTLst.push({ pt: featurePT, kind: LGXEnums.AuxPointKind.end });

        //顶部中点
        x = this.depth / 2;
        y = halfhgt;
        worldPt = mtx.MultT({ x, y, z: 0 });
        featurePT = { x: worldPt.x, y: worldPt.y, kind: 2 };
        featurePT = this.convertPt2World(featurePT,transformInfo);
        tFeaturePTLst.push({ pt: featurePT, kind: LGXEnums.AuxPointKind.lineMid });

        //左上顶点
        x = -halfwid + this.depth;
        y = halfhgt;
        worldPt = mtx.MultT({ x, y, z: 0 });
        featurePT = { x: worldPt.x, y: worldPt.y, kind: 2 };
        featurePT = this.convertPt2World(featurePT,transformInfo);
        tFeaturePTLst.push({ pt: featurePT, kind: LGXEnums.AuxPointKind.end });

        //前平面与后平面顶点连线中点
        //左上顶点
        x = -halfwid + this.depth / 2;
        y = halfhgt - this.depth / 2;
        worldPt = mtx.MultT({ x, y, z: 0 });
        featurePT = { x: worldPt.x, y: worldPt.y, kind: 2 };
        featurePT = this.convertPt2World(featurePT,transformInfo);
        tFeaturePTLst.push({ pt: featurePT, kind: LGXEnums.AuxPointKind.lineMid });

        //右上顶点
        x = halfwid - this.depth / 2;
        y = halfhgt - this.depth / 2;
        worldPt = mtx.MultT({ x, y, z: 0 });
        featurePT = { x: worldPt.x, y: worldPt.y, kind: 2 };
        featurePT = this.convertPt2World(featurePT,transformInfo);
        tFeaturePTLst.push({ pt: featurePT, kind: LGXEnums.AuxPointKind.end });

        //右下顶点
        x = halfwid - this.depth / 2;
        y = -halfhgt + this.depth / 2;
        worldPt = mtx.MultT({ x, y, z: 0 });
        featurePT = { x: worldPt.x, y: worldPt.y, kind: 2 };
        featurePT = this.convertPt2World(featurePT,transformInfo);
        tFeaturePTLst.push({ pt: featurePT, kind: LGXEnums.AuxPointKind.end });
    }

    getLocalOrigin() {
        let pt = { x: 0, y: 0 };
        pt.x = this._position.x;
        pt.y = this._position.y;
        return pt;
    }

    //复制粘贴时，从复制源对象复制属性到本图形对应属性----虚函数，由实体继承类实现
    copySubPropFromBuf(info,tx,ty){
        this.width = info.width;
        this.height = info.height;
        this.depth = info.depth;

        if (info.coverFillDef){
            this.coverFillDef.clone(info.coverFillDef);
            // this.coverFillDef.translate(tx,ty);
        }

        if (info.rightFillDef){
            this.rightFillDef.clone(info.rightFillDef);
            // this.rightFillDef.translate(tx,ty);
        }
        this.copyCommnonPropFromBuf(info,tx,ty);
    }

    //检测point点是否落在当前图形对象的边界上
    chPtOnEdge(point, scaling) {
        let flag = false;
        let transformInfo = new absgraph.TransformInfo();
        let tFeaturePTLst = [];
        this.getMainFeaturePTLst(tFeaturePTLst, transformInfo);
        tFeaturePTLst.forEach(ele => {
            let dis = funcs.distancePoint(ele.pt,point, scaling);
            if (dis < global.SelectGap) {
                flag = true;
                return ;
            }
        });
        return flag;
    }

    //设置被选中，并且加入数据管理类选中图形队列中。单选时调用
    setSelect(v) {
        this._selected = v;
        this.notifySelectToObserver(v);
        this.calSureSelPart(v);
    }

    //多选时调用，把当前图形对象加入数据管理类选中图形队列中
    setToSelectList() {
        this.notifySelectToObserver(1);
        this.calSureSelPart(true);
    }
    forseSetSelect(v) {
        this._selected = v;
        this.calSureSelPart(v);
    }//强制设置选中标识，不通知图形管理类

    calSureSelPart(v) {
        if (v) {
            let mtx = this.getLocalMatrix();

             //顶盖左下角
            let y1 = this.height / 2 - this.depth;
            //左上角
            let y2 = this.height / 2;

            //顶平面中心
            let x = 0;
            let y = (y1 + y2)/2;
            let topCoverWorldCnt = mtx.MultT({ x, y, z: 0 });
            let dis1 = funcs.distancePoint(topCoverWorldCnt, this.lastMouseDownPt, 1);
            
            let cmpInfoList = [];
            let t = {kind:1,dis:dis1};
            cmpInfoList.push(t);

            //主体中心
            let bodyCnt = mtx.MultT({ x: 0, y: 0, z: 0 });
            let dis2 = funcs.distancePoint(bodyCnt, this.lastMouseDownPt, 1);

            t = {kind:2,dis:dis2};
            cmpInfoList.push(t);


            //右侧面
            x = this.width/2 -this.depth / 2;
            y = this.height/2;
            let rightSideCnt = mtx.MultT({ x, y, z: 0 });
            let dis3 = funcs.distancePoint(rightSideCnt, this.lastMouseDownPt, 1);

            t = {kind:3,dis:dis3};
            cmpInfoList.push(t);

            let sortedList = cmpInfoList.sort(function (p1, p2) {
                if ((p1.dis - p2.dis) > 0) {
                    return 1;
                }
                else {
                    return -1;
                }
            }
            );

            this.sureSelKind = sortedList[0].kind;
        }
        else {
            this.sureSelKind = 0;
        }
    }

    getFillDef(){
        if (this.sureSelKind == 1){
            return this.coverFillDef;
        }
        else if (this.sureSelKind == 3){
            return this.rightFillDef;
        }
        else //if (this.sureSelKind == 2)
        {
            return this._fillDef;
        }
    }
}

export default { CubeGraph }
